package com.yike.user.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yike.common.enums.MachineCodeEnum;
import com.yike.common.exception.BusinessException;
import com.yike.common.redis.RedisUtil;
import com.yike.common.tool.CommonUtil;
import com.yike.common.tool.LoginUtil;
import com.yike.common.vo.ShopVo;
import com.yike.user.convert.MachineConvert;
import com.yike.user.convert.ShopConvert;
import com.yike.user.entity.Machine;
import com.yike.user.entity.Shop;
import com.yike.user.mapper.MachineMapper;
import com.yike.user.param.BandMachineParam;
import com.yike.user.param.InitMachineParam;
import com.yike.user.service.MachineService;
import com.yike.user.param.MachinePageParam;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yike.common.base.BaseServiceImpl;
import com.yike.common.pagination.Paging;
import com.yike.common.pagination.PageInfo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yike.user.service.ShopService;
import com.yike.common.vo.MachineVo;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.Date;
import java.util.UUID;

/**
 * 设备表 服务实现类
 *
 * @author yike
 * @since 2024-07-19
 */
@Slf4j
@Service
public class MachineServiceImpl extends BaseServiceImpl<MachineMapper, Machine> implements MachineService {

    @Resource
    private MachineMapper machineMapper;

    @Autowired
    private ShopService shopService;

    @Autowired
    private CommonUtil commonUtil;

    @Autowired
    private RedisUtil redisUtil;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveMachine(Machine machine) throws Exception {
        return super.save(machine);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateMachine(Machine machine) throws Exception {
        return super.updateById(machine);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteMachine(Long id) throws Exception {
        return super.removeById(id);
    }

    @Override
    public Paging<Machine> getMachinePageList(MachinePageParam machinePageParam) throws Exception {
        Page<Machine> page = new PageInfo<>(machinePageParam, OrderItem.desc(getLambdaColumn(Machine::getCreateTime)));
        LambdaQueryWrapper<Machine> wrapper = new LambdaQueryWrapper<>();
        IPage<Machine> iPage = machineMapper.selectPage(page, wrapper);
        return new Paging<Machine>(iPage);
    }

    @Override
    public MachineVo init(InitMachineParam machineParam) {
        // 获取用户真实密码
        String macNo = commonUtil.getDecryptStr(machineParam.getMacNo(), machineParam.getSaltKey(), null);

        Wrapper wrapper = Wrappers.lambdaQuery(Machine.class).eq(Machine::getMacNo, macNo);
        Machine machine = machineMapper.selectOne(wrapper);
        if (ObjectUtil.isNull(machine)) {
            throw new BusinessException(MachineCodeEnum.MACHINE_NO_EXSIT);
        }
        if (ObjectUtil.isNull(machine.getBindTime())) {
            throw new BusinessException(MachineCodeEnum.MACHINE_NO_BAND);
        }
        MachineVo machineVo = MachineConvert.INSTANCE.convert(machine);
        Shop shop = shopService.getById(machine.getShopId());
        machineVo.setShopName(shop.getShopName());
        machineVo.setShopNo(shop.getShopNo());

        // 登录成功保存token信息
        String token = UUID.randomUUID().toString();
        machineVo.setToken(token);

        // 将信息放入Redis，有效时间2小时
        redisUtil.set(token, machineVo, 12 * 60 * 60);

        // 记录设备登录token
        LoginUtil.saveMachineTokenSet(machine.getId(), token);

        return machineVo;
    }

    @Override
    public void band(BandMachineParam band) {
        Wrapper wrapper = Wrappers.lambdaQuery(Machine.class).eq(Machine::getMacNo, band.getMacNo());
        Machine machine = machineMapper.selectOne(wrapper);
        if (ObjectUtil.isNull(machine)) {
            machine = MachineConvert.INSTANCE.convert(band);
            machine.setBindTime(new Date());
            machine.setName(machine.getMacNo());
            machineMapper.insert(machine);
        } else if (ObjectUtil.isNotNull(machine.getBindTime())) {
            throw new BusinessException(500, "设备已绑定");
        } else {
            Shop shop = shopService.getById(band.getShopId());
            if(ObjectUtil.isNull(shop)){
                throw new BusinessException(500, "店铺不存在");
            }
            machine.setShopId(band.getShopId());
            machine.setBindTime(new Date());
            machineMapper.updateById(machine);
        }
    }

}
